import { MODEL_NAME } from '../../constants/model-names';
import {
  SECT_JOB,
  SECT_JOB_DATA,
  SECT_JOB_NUMBER,
  SECT_TASK_TYPE,
} from '../../data/sect/type';
import { EVENTS, type IEventBus } from '../../events';
import type { BaseSnapshot } from '../../systems/save';
import { BaseModel } from '../base';
import { SectCultivationSpotManager } from './sect-cultivation-spot';
import { SectManager } from './sect-manager';
import { SectTaskManager } from './sect-task-manager';
import type {
  SectJobListItem,
  SectListItem,
  SectScriptureListItem,
} from './type';

export interface SectmV1 extends BaseSnapshot {
  version: 1;
  /** 当前宗门 */
  currentSect: string | null;
  /** 当前宗门职位 */
  sectJob: number;
  /** 当前宗门贡献度 */
  sectContribution: number;
  /** 当前执行挂机任务 id */
  currentHangUpTaskId: string | null;
  /** 挂机任务已用时间 */
  hangUpUseTime: number;
  /** 修炼场有效次数 */
  cultivationSpotValidCount: number;
}

export type SectmSnapshot = SectmV1;

export type SectmSnapshotOld = SectmV1;

export class SectModel extends BaseModel {
  public name = MODEL_NAME.SECT;
  private bus: IEventBus;
  private sectManager: SectManager = new SectManager();
  private sectTaskManager = new SectTaskManager();
  private sectCultivationSpotManager = new SectCultivationSpotManager();
  private sectList: SectListItem[] = [];
  private sectJob: number = SECT_JOB_NUMBER[SECT_JOB.OUTER_SERVANT];
  private sectJobList: SectJobListItem[] = [];
  private sectScriptureList: SectScriptureListItem[] = [];

  constructor(bus: IEventBus) {
    super();
    this.bus = bus;

    this.sectJobList = SECT_JOB_DATA.map((job) => {
      return {
        config: job,
      };
    });
  }

  /** 加入宗门 */
  public joinSect(sectId: string) {
    if (this.sectManager.getSectById(sectId) === null) return;
    this.sectManager.setCurrentSectId(sectId);
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
    this.bus.emit(EVENTS.SECT_JOIN_SUCCESS);
  }

  /** 获取当前宗门 */
  public getCurrentSect() {
    const id = this.sectManager.getCurrentSectId();
    if (!id) return null;
    const sect = this.sectList.find((sect) => sect.config.id === id);
    if (!sect) return null;
    return sect;
  }

  /** 获取宗门列表配置 */
  public getSectConfigs() {
    return this.sectManager.getSects();
  }

  /** 设置宗门列表 */
  public setSectList(sectList: SectListItem[]) {
    this.sectList = sectList;
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 获取宗门列表 */
  public getSectList() {
    return this.sectList;
  }

  /** 获取宗门职位等级 */
  public getSectJob() {
    return this.sectJob;
  }

  /** 获取挂机任务进度 */
  public getHangUpTaskProgress() {
    return this.sectTaskManager.getProgress();
  }

  /** 宗门挂机任务更新方法 */
  public updateHangUpTask(dt: number) {
    this.sectTaskManager.updateHangUpTask(dt, {
      onComplete: () => {
        this.bus.emit(EVENTS.SECT_HANG_UP_TASK_COMPLETED);
      },
    });
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 开始挂机任务 */
  public startHangUpTask(id: string) {
    this.sectTaskManager.setCurrentHangUpTaskId(id);
    this.sectTaskManager.startHangUpTask();
  }

  /** 重置宗门挂机任务进度 */
  public resetProgress() {
    this.sectTaskManager.resetProgress();
  }

  /** 增加宗门贡献度 */
  public addSectContribution(num: number) {
    if (num <= 0) return;
    const currentContribution = this.sectManager.getCurrentSectContribution();
    const newContribution = currentContribution + num;
    this.sectManager.setCurrentSectContribution(newContribution);
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 获取当前进行中的挂机任务 id */
  public getCurrentHangUpTaskId() {
    return this.sectTaskManager.getCurrentHangUpTaskId();
  }

  /** 获取当前宗门修炼场地配置 */
  public getCurrentCultivationSpotConfig() {
    const currentSect = this.getCurrentSect();
    if (!currentSect) return null;
    return currentSect.cultivationSpotConfig;
  }

  /** 获取当前宗门挂机任务列表 */
  public getCurrentSectHangUpTaskList() {
    const currentSect = this.getCurrentSect();
    if (!currentSect) return [];
    return currentSect.sectTaskList.filter(
      (task) => task.config.type === SECT_TASK_TYPE.HANG_UP
    );
  }

  /** 获取当前宗门普通任务列表 */
  public getCurrentSectNormalTaskList() {
    const currentSect = this.getCurrentSect();
    if (!currentSect) return [];
    return currentSect.sectTaskList.filter(
      (task) => task.config.type === SECT_TASK_TYPE.NORMAL
    );
  }

  /** 获取当前进行中的挂机任务 */
  public getCurrentHangUpTaskConfig() {
    const id = this.getCurrentHangUpTaskId();
    if (!id) return null;
    const task = this.getCurrentSectHangUpTaskList().find(
      (task) => task.config.id === id
    );
    if (!task) return null;
    return task;
  }

  /** 获取修炼场有效次数 */
  public getSectCultivationSpotValidCount() {
    return this.sectCultivationSpotManager.getValidCount();
  }

  /** 设置修炼场有效次数 */
  public setSectCultivationSpotValidCount(validCount: number) {
    this.sectCultivationSpotManager.setValidCount(validCount);
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 购买修炼场有效次数 */
  public buySectCultivationSpotValidCount() {
    this.sectCultivationSpotManager.addValidCount();
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 是否有修炼加成次数 */
  public hasSectCultivationSpotValidCount() {
    return this.sectCultivationSpotManager.hasValidCount();
  }

  /** 扣除 1 次修炼加成次数 */
  public reduceSectCultivationSpotValidCount() {
    const validCount = this.sectCultivationSpotManager.getValidCount();
    const newValidCount = validCount - 1;
    this.sectCultivationSpotManager.setValidCount(newValidCount);
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 获取宗门挂机任务需要的时间 */
  public getHangUpTaskIncomeTime() {
    return this.sectTaskManager.getHangUpTaskIncomeTime();
  }

  /** 根据职位等级获取职位配置 */
  public getSectJobConfigById(level: number) {
    const config = this.sectJobList.find((job) => job.config.level === level);
    return config ? config : null;
  }

  /** 获取当前职位等级配置 */
  public getCurrentSectJob() {
    return this.getSectJobConfigById(this.sectJob);
  }

  /** 获取职位列表 */
  public getSectJobList() {
    return this.sectJobList;
  }

  /** 职位升级 */
  public upgradeSectJob() {
    this.sectJob += 1;
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 扣除宗门贡献度 */
  public reduceSectContribution(num: number) {
    if (num <= 0) return;
    const currentContribution = this.sectManager.getCurrentSectContribution();
    const newContribution = currentContribution - num;
    this.sectManager.setCurrentSectContribution(Math.max(0, newContribution));
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 获取宗门当前贡献度 */
  public getCurrentSectContribution() {
    return this.sectManager.getCurrentSectContribution();
  }

  /** 设置藏书阁列表 */
  public setSectScriptureList(sectScriptureList: SectScriptureListItem[]) {
    this.sectScriptureList = sectScriptureList;
    this.bus.emit(EVENTS.SECT_STATE_UPDATE);
  }

  /** 获取藏书阁列表 */
  public getSectScriptureList() {
    return this.sectScriptureList;
  }

  public get uiState() {
    return {
      currentSect: this.sectManager.getCurrentSect(),
      sectList: this.getSectList(),
      hangUpTaskProgress: this.getHangUpTaskProgress(),
      hangUpTaskProgressLeftTime: this.sectTaskManager.getLeftTime(),
      sectHangUpTaskList: this.getCurrentSectHangUpTaskList(),
      sectNormalTaskList: this.getCurrentSectNormalTaskList(),
      currentHangUpTask: this.getCurrentHangUpTaskConfig(),
      sectContribution: this.getCurrentSectContribution(),
      sectSpotConfig: this.getCurrentCultivationSpotConfig(),
      cultivationSpotValidCount: this.getSectCultivationSpotValidCount(),
      sectJobList: this.getSectJobList(),
      currentSectJob: this.getCurrentSectJob(),
      sectScriptureList: this.getSectScriptureList(),
    };
  }

  public save(): SectmSnapshot {
    const currentSect = this.sectManager.getCurrentSect();
    const currentHangUpTaskId = this.sectTaskManager.getCurrentHangUpTaskId();
    return {
      version: 1,
      currentSect,
      sectJob: this.getSectJob(),
      sectContribution: this.sectManager.getCurrentSectContribution(),
      currentHangUpTaskId,
      hangUpUseTime: this.sectTaskManager.getHangUpUseTime(),
      cultivationSpotValidCount: this.getSectCultivationSpotValidCount(),
    };
  }

  public load(data: SectmSnapshot) {
    this.sectManager.setCurrentSectId(data.currentSect);
    this.sectJob = data.sectJob || SECT_JOB_NUMBER[SECT_JOB.OUTER_SERVANT];
    this.sectManager.setCurrentSectContribution(data.sectContribution || 0);
    if (data.currentHangUpTaskId) {
      this.sectTaskManager.setCurrentHangUpTaskId(data.currentHangUpTaskId);
    }
    this.sectCultivationSpotManager.setValidCount(
      Math.max(0, data.cultivationSpotValidCount || 0)
    );
    this.sectTaskManager.setHangUpUseTime(data.hangUpUseTime || 0);
  }
}
